/*
 * io.c - 
 */

#include <io.h>
#include <utils.h>

/**************/
/** Screen  ***/
/**************/

#define NUM_COLUMNS 80
#define NUM_ROWS    25

Byte x, y=15;

/* Read a byte from 'port' */
Byte inb (unsigned short port)
{
  Byte v;

  __asm__ __volatile__ ("inb %w1,%0":"=a" (v):"Nd" (port));
  return v;
}

void scroll(void)
{
	DWord screen1, screen2;
	int i;
	for (i = 0; i < NUM_ROWS-1; ++i)
	{
		screen1 = 0xb8000 + (i * NUM_COLUMNS) * 2;
		screen2 = 0xb8000 + ((i+1) * NUM_COLUMNS) * 2;

		copy_data((void *)screen2, (void *)screen1, NUM_COLUMNS * 2);
	}

	int j;
	Word borra = (Word)(' ' & 0xFF) | 0x200;
	for(j = 0; j < NUM_COLUMNS; j++)
	{
		screen1 = 0xb8000 + ((NUM_ROWS-1) * NUM_COLUMNS + j) * 2;
		__asm__ ("movw %0, (%1)\n" : : "g"(borra), "g"(screen1));
	}
}

void printc(char c)
{
	Word ch;
	DWord screen;

	if(c == '\n')
	{
		x = 0;
		y++;
	}
	else 
	{
		if (x >= NUM_COLUMNS)
	  	{
			x = 0;
			y++;
		 	
		}
		if (y >= NUM_ROWS)
		{
			  	scroll();
				y = NUM_ROWS-1;
		}
	}

    ch = (Word) (c & 0x00FF) | 0x0200;
		screen = 0xb8000 + (y * NUM_COLUMNS + x) * 2;
		__asm__ __volatile__ ( "movb %0, %%al; outb $0xe9" ::"a"(c));
		asm("movw %0, (%1)" : : "g"(ch), "g"(screen));
		++x;
	
}

void printk(char *string)
{
  int i;
  for (i = 0; string[i]; i++)
    printc(string[i]);
}

void printNum(int n)
{
	char buffer[12];
	itoa(n, buffer);
	printk(buffer);
	printk("\n");
}

void print_xy(int x, int y, char c)
{
	Word ch = (Word) (c & 0x00FF) | 0x0200;
	DWord screen = 0xb8000 + (y * NUM_COLUMNS + x) * 2;
	//__asm__ __volatile__ ( "movb %0, %%al; outb $0xe9" ::"a"(c));

	asm("movw %0, (%1)" : : "g"(ch), "g"(screen));
}

void printk_xy(int x, int y, char *string)
{
	int i;
	for(i = 0; string[i]; ++i)
	{
		print_xy(x, y, string[i]);
		++x;
		if(x == NUM_COLUMNS)
		{
			x = 0;
			++y;
		}
	}
}

